home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / Var / VarStack.c < prev   
C/C++ Source or Header  |  1996-09-26  |  8KB  |  324 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     varstack.c
  5.  
  6.     DESCRIPTION
  7.     Variable Stack for DME/XDME
  8.  
  9.     NOTES
  10.     -/-
  11.  
  12.     BUGS
  13.     <none known>
  14.  
  15.     TODO
  16.     -/-
  17.  
  18.     EXAMPLES
  19.     -/-
  20.  
  21.     SEE ALSO
  22.     vars.c
  23.  
  24.     INDEX
  25.  
  26.     HISTORY
  27.     05-12-92 b_noll created
  28.     26-08-93 VSTK_drop added
  29.     24-06-94 renamed VARS to VRST
  30.  
  31. ******************************************************************************/
  32.  
  33. /*
  34. **  (C)Copyright 1992 by Bernd Noll for null/zero-soft
  35. **  All Rights Reserved
  36. **
  37. **  RCS Header: $Id: varstack.c,v 1.65 92/12/05 12:47:24 b_noll Exp $
  38. **
  39. **
  40. *!**********************************************************
  41. *!
  42. *!  Variable Stacking:
  43. *!
  44. *!  Stacking for all structures, which may be read and
  45. *!  written via GetTypedVar()
  46. *!  (Please notice that stackable are only variables,
  47. *!   not macros, menues or mappings (they are stackable, but
  48. *!   popping or picking might fail))
  49. *!
  50. *!  Users should be aware to pop their entries from the stack
  51. *!  when they are needed not any more
  52. *!  (We have NOT planned to create a garbage-collector :-))
  53. *!
  54. ************************************************************
  55. **
  56. **  Implementator's note:
  57. **
  58. **  variable stacking is done in a quiet simple way:
  59. **  all variables are searched with gettypedvar and their types
  60. **  are used as Node.ln_Type - entry
  61. **
  62. **  currently (12-92) we use the same structure for storing variables
  63. **  on varstack which is used for storage in the main variable
  64. **  lists, but I preferred redefining that structure, as this method
  65. **  gives us the possibility of changing our definitions locally.
  66. **  (This is as we are just implementing AVL-Trees for Varstorage)
  67. */
  68.  
  69. /**************************************
  70.         Includes
  71. **************************************/
  72.  
  73.  
  74.  
  75. #include "defs.h"
  76. #ifdef PATCH_NULL
  77. #include "COM.h"
  78. #include "libs/AUTO.h"
  79. #endif
  80.  
  81. /**************************************
  82.         Globale Exports
  83. **************************************/
  84. Prototype void do_pushVAR  (void);
  85. Prototype void do_pickVAR  (void);
  86. Prototype void do_popVAR   (void);
  87. Prototype void do_swapVAR  (void);
  88. Prototype void do_purgeVAR (void);
  89.  
  90.  
  91. /**************************************
  92.       Interne Defines & Strukturen
  93. **************************************/
  94. #define MLIST struct MinList
  95. #define MNODE struct MinNode
  96.  
  97. static MLIST varstack =
  98. { (MNODE*)&varstack.mlh_Tail, NULL, (MNODE*)&varstack.mlh_Head };
  99.  
  100. typedef struct _VRST
  101. {
  102.     NODE    Node;
  103.     char*   Str;
  104. } VRST;
  105.  
  106.  
  107. /**************************************
  108.        Interne Prototypes
  109. **************************************/
  110.  
  111. void VSTK_drop (VRST *);
  112.  
  113. /**************************************
  114.        Impementation
  115. **************************************/
  116.  
  117.  
  118. /*
  119. *! >PUSHVAR varname
  120. *!
  121. *!    push the contents of the variable varname onto variable-stack
  122. *!
  123. */
  124.  
  125. void do_pushVAR (void)
  126. {
  127.     VRST *v;
  128.     int type;
  129.  
  130.     if ((v = malloc (sizeof (VRST))))
  131.     {                        /* allocate a node */
  132.     setmem(v, sizeof (VRST), 0);
  133.     v->Node.ln_Name = strdup (av[1]);       /* and space for name and value */
  134.     v->Str = GetTypedVar (av[1], &type);
  135.     if (v->Node.ln_Name && v->Str)
  136.     {                    /* if its done, fill in all values and push the node onto the varstack */
  137.         v->Node.ln_Type = type;
  138.         AddHead((LIST*)&varstack, (NODE*)v);
  139.     } else
  140.     {                    /* else free all what You have already allocated */
  141.         if (v->Node.ln_Name)
  142.         {
  143.         error ("%s: failure!\nno memory", av[0]);
  144.         free(v->Node.ln_Name);
  145.         } /* if */
  146.         if (v->Str)
  147.         {
  148.         error ("%s: failure!\nno memory or unknown variable", av[0]);
  149.         free(v->Str);
  150.         } /* if */
  151.         free(v);
  152.  
  153.     } /* if (not) malloced|found */
  154.     } else
  155.     {
  156.     error ("%s: no memory for stack-entry", av[0]);
  157.     } /* if (not) malloced */
  158. } /* do_pushVAR */
  159.  
  160.  
  161.  
  162. /*
  163. *! >POPVAR varname
  164. *!
  165. *!    get the latest to variable-stack pushed contents of the variable
  166. *!    varname back and free the stack-entry
  167. *!
  168. */
  169.  
  170. void do_popVAR (void)
  171. {
  172.     VRST *v;
  173.  
  174.     if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
  175.     {                             /* if there is a matching stack-entry */
  176.     SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to its name with its contents */
  177.     VSTK_drop (v);                               /* and drop the entry */
  178.     } else
  179.     {
  180.     error ("%s: stackentry %s not found", av[0], av[1]);
  181.     } /* if (not) found */
  182. } /* do_popVAR */
  183.  
  184.  
  185.  
  186. /*
  187. *! >PICKVAR varname
  188. *!
  189. *!    get the latest to variable-stack pushed contents of the variable
  190. *!    varname back without freeing the stack-entry
  191. *!
  192. */
  193.  
  194. void do_pickVAR (void)
  195. {
  196.     VRST *v;
  197.  
  198.     if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
  199.     {                             /* if there is a matching stack-entry */
  200.     SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to its name with its contents */
  201.     } else
  202.     {
  203.     error ("%s: stackentry %s not found", av[0], av[1]);
  204.     } /* if (not) found */
  205. } /* do_pickVAR */
  206.  
  207.  
  208.  
  209. /*
  210. *! >SWAPVAR varname
  211. *!
  212. *!    swap the contents of the variable varname and of its first occurancy in variable-stack
  213. *!
  214. **  this is not a very effective way of change, I would say,
  215. **  but it is one of the shortest
  216. */
  217.  
  218. void do_swapVAR (void)
  219. {
  220.     VRST *v;
  221.  
  222.     if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
  223.     {                         /* if there is a matching stack-entry */
  224.     Remove((NODE*)v);                        /* remove it */
  225.     do_pushVAR();                            /* push the variables current contents onto stack */
  226.     AddHead((LIST*)&varstack, (NODE*)v);     /* set the elder stack-entry before that new node */
  227.     do_popVAR();                             /* and then pop it into the variable */
  228.     } else
  229.     {
  230.     error ("%s: stackentry %s not found", av[0], av[1]);
  231.     } /* if (not) found */
  232. } /* do_swapVAR */
  233.  
  234.  
  235.  
  236. /*
  237. *! >PURGEVAR varname
  238. *!
  239. *!    remove all entries with the name varname from varstack
  240. *!
  241. */
  242.  
  243. void do_purgeVAR (void)
  244. {
  245.     VRST *v;
  246.     VARS *w;
  247.  
  248.     /* ---- we cannot use GetSucc() here, since we would take the successor of a freed node =8-( */
  249.  
  250.     for (v = (VRST *)varstack.mlh_Head; (w = (VRST *)v->Node.ln_Succ) != NULL; v = w) /* for all nodes ... */
  251.     if (strcmp(v->Node.ln_Name, av[1]) == 0)                                      /* if they match ... */
  252.         VSTK_drop (v);                                                            /* drop them ...     */
  253. } /* do_purgeVAR */
  254.  
  255.  
  256. void do_dropVAR (void)
  257. {
  258.     VRST *v;
  259.     if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))    /* find them first matching node */
  260.     VSTK_drop (v);                                      /* ... and drop it               */
  261. } /* do_dropVAR */
  262.  
  263.  
  264. void VSTK_drop (VRST *v)
  265. {
  266.     /* ---- Remove an entry from the stack, and free its contents and itself */
  267.  
  268.     if (v)
  269.     {
  270.     Remove((NODE*)v);
  271.     free(v->Str);
  272.     free(v->Node.ln_Name);
  273.     free(v);
  274.     } /* if */
  275. } /* VSTK_drop */
  276.  
  277.  
  278.  
  279.  
  280. #ifdef PATCH_NULL
  281.  
  282. static const
  283. struct CommandNode VSTK_Commands[] =
  284. {
  285.     {ENODE("pickvar"),       1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_pickVAR  },
  286.     {ENODE("popvar"),        1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_popVAR   },
  287.     {ENODE("pushvar"),       1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_pushVAR  },
  288.     {ENODE("purgevar"),      1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_purgeVAR },
  289.     {ENODE("swapvar"),       1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_swapVAR  },
  290.     {ENODE("dropvar"),       1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_dropVAR  },
  291. };
  292.  
  293. MK_AUTOINIT(VSTK_Init)
  294. {
  295.     int i;
  296.  
  297.     NewList ((struct List*)&varstack);
  298.  
  299.     for (i = sizeof (VSTK_Commands)/sizeof (struct CommandNode) - 1;i >= 0; --i)
  300.     COM_Add (&VSTK_Commands[i]);
  301. } /* VSTK_Init */
  302.  
  303.  
  304. MK_AUTOEXIT(VSTK_Exit)
  305. {
  306.     int  i;
  307.     APTR lock;
  308.     VRST*v;
  309.  
  310.     while ((v = GetHead (&varstack)))
  311.     VSTK_drop (v);
  312.  
  313.     for (i = sizeof (VSTK_Commands)/sizeof (struct CommandNode) - 1; (i >= 0); DEC(i))
  314.     if ((lock = COM_Lock (VSTK_Commands[i].Node.ln_Name)))
  315.         COM_Remove (lock);
  316. } /* VSTK_Exit */
  317. #endif
  318.  
  319.  
  320. /******************************************************************************
  321. *****  ENDE varstack.c
  322. ******************************************************************************/
  323.  
  324.